Hadoop之Hbase架构环境搭建及使用JAVA API远程连接

0x00 前言

Hbase全称为Hadoop Database,是一个分布式的存储系统。Hbase使用Hadoop的HDFS作为其文件存储系统,使用Hadoop的MapReduce来处理Hbase中的海量数据,使用zookeeper作为其协调工具。

查看本教程之前,请确保已安装配置好Hadoop,可参考Centos7搭建Hadoop伪分布式集群详细步骤,使用Hadoop JAVA API 远程连接HDFS

0x01 下载安装

下载

首先在官网下载Hbase

选择对应版本的bin文件,国内根据推荐的清华源下载即可。

linux下可使用wget命令下载,我下载的为2.1.4版本

1
wget http://mirrors.tuna.tsinghua.edu.cn/apache/hbase/2.1.4/hbase-2.1.4-bin.tar.gz

解压

下载后即可解压到目录,我这里直接在当前目录解压

1
tar -zxvf hbase-2.1.4-bin.tar.gz

配置环境变量

进入解压后的目录使用pwd命令查看路径

然后修改.bashrc配置环境变量

1
2
3
4
5
vi ~/.bashrc
在最后添加
export HBASE_HOME=/home/wzb/hbase-2.1.4
export PATH=$PATH:$HBASE_HOME/bin
保存后退出


然后使用source ~/.bashrc命令使配置生效
然后输入命令hbase可看到环境变量配置成功

0x02 启动Hbase

在启动hbase之前。首先进行相应的配置修改

配置hbase-env.sh

修改hbase所在目录下的conf目录的hbase-env.sh
如我的位置为/home/wzb/hbase-2.1.4/conf/hbase-env.sh
首先配置环境变量export JAVA_HOME=/usr/local/java/jdk1.8.0_201,此处修改为你的java环境变量,如不知道,可通过echo $JAVA_HOME查看
然后配置export HBASE_MANAGES_ZK=true,使用其自带的zookeeper

配置hbase-site.xml

然后继续配置conf目录下的hbase-site.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<configuration>
<property>
<name>hbase.rootdir</name>
<value>hdfs://192.168.111.147:9000/hbase</value>
</property>
<property>
<name>hbase.zookeeper.quorum</name>
<value>192.168.111.147</value>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<property>
<name>hbase.zookeeper.property.dataDir</name>
<value>/home/wzb/Hbase/zookeeper/tmp</value>
</property>
<property>
<name>hbase.unsafe.stream.capability.enforce</name>
<value>false</value>
</property>
<property>
<name>hbase.wal.provider</name>
<value>filesystem</value>
</property>

</configuration>

注意标识处根据自己环境修改

下载htrace-core-3.1.0-incubating.jar

下载htrace-core-3.1.0-incubating.jar并移至hbase安装目录下的lib文件夹

启动start-hbase.sh

配置修改好后即可通过start-hbase.sh命令启动
在启动之前,请先使用start-all.sh启动hadoop相关进程

然后即可使用命令start-hbase.sh启动hbase

通过jps可看到比刚才多出来HMaster HRegionServer HQuorumPeer三个进程,如后面出现错误可看查这些进程是否正常启动,如未启动移步文章末尾问题解决可查笔者记录的解决办法。

访问apache Hbase

此处正常启动后继续
然后通过浏览器访问http://192.168.111.147:16010/master-status
此处ip即为你在hbase-site.xml文件中配置的ip

至此Hbase启动成功。

0x03 Hbase shell

hbase提供了一个shell的终端给用户交互。使用命令hbase shell进入命令界面。通过执行 help可以看到命令的帮助信息。

下图列出常用命令

更过命令操作可参考HBase shell 命令介绍

0x04 Java API连接Hbase

修改hosts

因为Hbase 16000端口绑定为127.0.0.1,所以通过其他主机无法访问,这里唯一的解决方法是修改hosts文件
修改linux hostname
sudo vi /etc/sysconfig/network
添加以下内容

1
2
NETWORKING=yes
HOSTNAME=master

修改linux hosts
su vi /etc/hosts
添加以下内容

1
192.168.111.147 master #此处ip添加你的linux ip,hostname填写上面修改的,我这里设置为master

linux配置完成后需重启系统,以使配置生效。

修改windows hosts文件
路径为:C:\Windows\System32\drivers\etc\hosts
该文件无权限直接修改,需复制出修改完再覆盖掉
最后添加一行192.168.111.147 master,同样此处应与上面相同。
配置完成后即可继续下面使用java api连接,不配置可能会导致无法连接。

JAVA API

关于java项目创建参见使用Hadoop JAVA API 远程连接HDFS
pom.xml中添加

1
2
3
4
5
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>1.2.4</version>
</dependency>

Hbase-site.xml添加到项目中,如下图

新建HBase类,内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package hadoop;

import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;


public class HBase {

public static Configuration conf;
public static Connection connection;
public static Admin admin;

public static void main(String[] args) throws IOException {

conf = HBaseConfiguration.create();
conf.set("hbase.master", "192.168.111.147:16000");

connection = ConnectionFactory.createConnection(conf);
admin = connection.getAdmin();

HTableDescriptor table = new HTableDescriptor(TableName.valueOf("table1"));
table.addFamily(new HColumnDescriptor("group1")); //创建表时至少加入一个列组

if(admin.tableExists(table.getTableName())){
admin.disableTable(table.getTableName());
admin.deleteTable(table.getTableName());
}
admin.createTable(table);
}

}

运行成功后成功创建table1

转到Hbase shell使用list命令可看到新表已创建

详细代码

将常用hbase api封装好了,直接在main函数中调用即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
package hadoop;

import java.io.File;
import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes;

public class HbaseTest {
public static Configuration configuration;
public static Connection connection;
public static Admin admin;

public static void main(String[] args) throws IOException {
//createTable("t2", new String[] { "cf1", "cf2" });
listTables();
/*
* insterRow("t2", "rw1", "cf1", "q1", "val1"); getData("t2", "rw1",
* "cf1", "q1"); scanData("t2", "rw1", "rw2");
* deleRow("t2","rw1","cf1","q1"); deleteTable("t2");
*/
}

// 初始化链接
public static void init() {
configuration = HBaseConfiguration.create();
/*
* configuration.set("hbase.zookeeper.quorum",
* "10.10.3.181,10.10.3.182,10.10.3.183");
* configuration.set("hbase.zookeeper.property.clientPort","2181");
* configuration.set("zookeeper.znode.parent","/hbase");
*/
//configuration.set("hbase.zookeeper.property.clientPort", "2181");
//configuration.set("hbase.zookeeper.quorum", "192.168.111.151");
configuration.set("hbase.master", "192.168.111.151:16000");
File workaround = new File(".");
System.getProperties().put("hadoop.home.dir",
workaround.getAbsolutePath());
new File("./bin").mkdirs();
try {
new File("./bin/test").createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
connection = ConnectionFactory.createConnection(configuration);
admin = connection.getAdmin();
} catch (IOException e) {
e.printStackTrace();
}
}

// 关闭连接
public static void close() {
try {
if (null != admin)
admin.close();
if (null != connection)
connection.close();
} catch (IOException e) {
e.printStackTrace();
}

}

// 建表
public static void createTable(String tableNmae, String[] cols) throws IOException {

init();
TableName tableName = TableName.valueOf(tableNmae);

if (admin.tableExists(tableName)) {
System.out.println("talbe is exists!");
} else {
HTableDescriptor hTableDescriptor = new HTableDescriptor(tableName);
for (String col : cols) {
HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(col);
hTableDescriptor.addFamily(hColumnDescriptor);
}
admin.createTable(hTableDescriptor);
}
close();
}

// 删表
public static void deleteTable(String tableName) throws IOException {
init();
TableName tn = TableName.valueOf(tableName);
if (admin.tableExists(tn)) {
admin.disableTable(tn);
admin.deleteTable(tn);
}
close();
}

// 查看已有表
public static void listTables() throws IOException {
init();
HTableDescriptor hTableDescriptors[] = admin.listTables();
for (HTableDescriptor hTableDescriptor : hTableDescriptors) {
System.out.println(hTableDescriptor.getNameAsString());
}
close();
}

// 插入数据
public static void insterRow(String tableName, String rowkey, String colFamily, String col, String val)
throws IOException {
init();
Table table = connection.getTable(TableName.valueOf(tableName));
Put put = new Put(Bytes.toBytes(rowkey));
put.addColumn(Bytes.toBytes(colFamily), Bytes.toBytes(col), Bytes.toBytes(val));
table.put(put);

// 批量插入
/*
* List<Put> putList = new ArrayList<Put>(); puts.add(put);
* table.put(putList);
*/
table.close();
close();
}

// 删除数据
public static void deleRow(String tableName, String rowkey, String colFamily, String col) throws IOException {
init();
Table table = connection.getTable(TableName.valueOf(tableName));
Delete delete = new Delete(Bytes.toBytes(rowkey));
// 删除指定列族
// delete.addFamily(Bytes.toBytes(colFamily));
// 删除指定列
// delete.addColumn(Bytes.toBytes(colFamily),Bytes.toBytes(col));
table.delete(delete);
// 批量删除
/*
* List<Delete> deleteList = new ArrayList<Delete>();
* deleteList.add(delete); table.delete(deleteList);
*/
table.close();
close();
}

// 根据rowkey查找数据
public static void getData(String tableName, String rowkey, String colFamily, String col) throws IOException {
init();
Table table = connection.getTable(TableName.valueOf(tableName));
Get get = new Get(Bytes.toBytes(rowkey));
// 获取指定列族数据
// get.addFamily(Bytes.toBytes(colFamily));
// 获取指定列数据
// get.addColumn(Bytes.toBytes(colFamily),Bytes.toBytes(col));
Result result = table.get(get);

showCell(result);
table.close();
close();
}

// 格式化输出
public static void showCell(Result result) {
Cell[] cells = result.rawCells();
for (Cell cell : cells) {
System.out.println("RowName:" + new String(CellUtil.cloneRow(cell)) + " ");
System.out.println("Timetamp:" + cell.getTimestamp() + " ");
System.out.println("column Family:" + new String(CellUtil.cloneFamily(cell)) + " ");
System.out.println("row Name:" + new String(CellUtil.cloneQualifier(cell)) + " ");
System.out.println("value:" + new String(CellUtil.cloneValue(cell)) + " ");
}
}

// 批量查找数据
public static void scanData(String tableName, String startRow, String stopRow) throws IOException {
init();
Table table = connection.getTable(TableName.valueOf(tableName));
Scan scan = new Scan();
// scan.setStartRow(Bytes.toBytes(startRow));
// scan.setStopRow(Bytes.toBytes(stopRow));
ResultScanner resultScanner = table.getScanner(scan);
for (Result result : resultScanner) {
showCell(result);
}
table.close();
close();
}

}

0x05 问题解决

此处容易出现的问题为HMaster启动后闪退。
可通过查看hbase安装目录下的logs文件内log日志确定该问题。

HDFS问题

首先查看hbase-wzb-master-wzb_node1.log,此处查看你的master日志文件

发现9000的HDFS连接失败
首先浏览器访问你的ip的9000端口,即hdfs服务,访问成功如下图

如果未访问成功,查看hadoop配置文件core-site.xml

查看hdfs是否正确配置为你的ip,不是请修改,确保hbase配置文件中连接的hdfs服务器与你启动的服务器路径相同。
配置成功后重启hadoop,再次访问

权限问题

同样查看日志问题,如发现前面配置的Hbase文件夹有权限问题,请将Hbase文件夹赋予777权限

1
chomd 777 Hbase //此处Hbase请添加你hbase-site.xml中配置的hbase.zookeeper.property.dataDir目录

zookeeper未正常启动问题

查看hbase-wzb-regionserver-wzb_node1.log此处应修改为你的regionservelog文件
出现以下错误说明zookeeper未启动成功。

首先查看sudo netstat -anp | grep 2181端口是否被占用,如果占用,找到占用程序并kill掉相关进程。

防火墙问题

如果出现其他端口无法访问问题,请关闭防火墙

1
2
3
systemctl stop firewalld.service #停止firewall

systemctl disable firewalld.service #禁止firewall开机启动

其他问题

配置过程中可能出现其他各种问题,可查看log文件出现的问题并解决。

本文标题:Hadoop之Hbase架构环境搭建及使用JAVA API远程连接

文章作者:boogle

发布时间:2019年04月10日 - 11:38

最后更新:2019年05月08日 - 10:38

原始链接:https://zhengbao.wang/Hadoop之Hbase架构环境搭建及使用JAVA API远程连接/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

感觉写的不错,给买个棒棒糖呗